// 网络请求工具类
const config = require("../config.js");
const BASE_URL = config.baseURL;

/**
 * 封装微信小程序网络请求
 * @param {Object} options 请求配置
 * @param {string} options.url 请求地址
 * @param {string} options.method 请求方法 GET/POST/PUT/DELETE
 * @param {Object} options.data 请求数据
 * @param {Object} options.header 请求头
 * @param {boolean} options.showLoading 是否显示加载中
 * @param {string} options.loadingText 加载中文字
 */
function request(options = {}) {
  return new Promise((resolve, reject) => {
    // 显示加载中
    if (options.showLoading !== false) {
      wx.showLoading({
        title: options.loadingText || "请求中...",
        mask: true,
      });
    }

    // 构建完整URL
    const url = options.url.startsWith("http")
      ? options.url
      : BASE_URL + options.url;

    // 默认请求头
    const header = {
      "Content-Type": "application/json",
      ...options.header,
    };

    // 添加Authorization header（如果存在token）
    const token = wx.getStorageSync("token");
    if (token) {
      header["Authorization"] = `Bearer ${token}`;
    }

    wx.request({
      url: url,
      method: options.method || "GET",
      data: options.data || {},
      header: header,
      timeout: 10000, // 设置10秒超时
      success: (res) => {
        // 隐藏加载中
        if (options.showLoading !== false) {
          wx.hideLoading();
        }

        // 处理响应
        if (res.statusCode === 200) {
          // 根据您的Go接口返回格式处理 (code: 0 表示成功)
          if (res.data.code === 0) {
            resolve(res.data);
          } else {
            // 业务错误 - 检查是否是token过期
            if (
              res.data &&
              res.data.message &&
              res.data.message.toLowerCase().includes("token") &&
              (res.data.message.toLowerCase().includes("无效") ||
                res.data.message.toLowerCase().includes("过期"))
            ) {
              // token过期，使用统一的处理
              const { handleTokenExpired } = require("./auth.js");
              handleTokenExpired();
              reject({
                data: res.data,
                statusCode: res.statusCode,
                errMsg: "request:ok",
              });
              return;
            }

            // 其他业务错误 - 不显示Toast，让调用方处理
            // 包装错误对象，保持与微信小程序错误格式一致
            reject({
              data: res.data,
              statusCode: res.statusCode,
              errMsg: "request:ok",
            });
          }
        } else {
          // HTTP错误 - 检查是否是token过期
          if (res.statusCode === 401) {
            // token过期，使用统一的处理
            const { handleTokenExpired } = require("./auth.js");
            handleTokenExpired();
            reject(res);
            return;
          }

          // 对于400错误，不显示轻提示，让调用方处理
          if (res.statusCode === 400) {
            reject(res);
            return;
          }

          // 其他HTTP错误显示轻提示
          wx.showToast({
            title: `请求失败(${res.statusCode})`,
            icon: "none",
            duration: 2000,
          });
          reject(res);
        }
      },
      fail: (err) => {
        // 隐藏加载中
        if (options.showLoading !== false) {
          wx.hideLoading();
        }

        // 网络请求失败

        // 根据错误类型显示不同的提示
        let errorMessage = "网络连接失败";
        if (err.errMsg && err.errMsg.includes("ERR_CONNECTION_REFUSED")) {
          errorMessage = "服务器连接失败，请检查服务器是否启动";
        } else if (err.errMsg && err.errMsg.includes("timeout")) {
          errorMessage = "请求超时，请检查网络连接";
        } else if (err.errMsg && err.errMsg.includes("network")) {
          errorMessage = "网络异常，请检查网络连接";
        }

        // 只在非静默模式下显示错误提示
        if (options.showLoading !== false) {
          wx.showToast({
            title: errorMessage,
            icon: "none",
            duration: 3000,
          });
        }
        reject(err);
      },
      complete: () => {
        // 确保在任何情况下都隐藏加载中
        if (options.showLoading !== false) {
          wx.hideLoading();
        }
      },
    });
  });
}

/**
 * GET请求
 * @param {string} url 请求地址
 * @param {Object} params 查询参数
 * @param {Object} options 其他配置
 */
function get(url, params = {}, options = {}) {
  // 将参数拼接到URL
  if (Object.keys(params).length > 0) {
    const queryString = Object.keys(params)
      .map(
        (key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
      )
      .join("&");
    url += (url.includes("?") ? "&" : "?") + queryString;
  }

  return request({
    url,
    method: "GET",
    ...options,
  });
}

/**
 * POST请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他配置
 */
function post(url, data = {}, options = {}) {
  return request({
    url,
    method: "POST",
    data,
    ...options,
  });
}

/**
 * PUT请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他配置
 */
function put(url, data = {}, options = {}) {
  return request({
    url,
    method: "PUT",
    data,
    ...options,
  });
}

/**
 * DELETE请求
 * @param {string} url 请求地址
 * @param {Object} options 其他配置
 */
function del(url, options = {}) {
  return request({
    url,
    method: "DELETE",
    ...options,
  });
}

// 文件上传方法
function upload(url, filePath, options = {}) {
  return new Promise((resolve, reject) => {
    // 显示加载中
    if (options.showLoading !== false) {
      wx.showLoading({
        title: options.loadingText || "上传中...",
        mask: true,
      });
    }

    // 构建完整URL
    const fullUrl = url.startsWith("http") ? url : BASE_URL + url;

    // 默认请求头
    const header = {
      ...options.header,
    };

    // 添加Authorization header（如果存在token）
    const token = wx.getStorageSync("token");
    if (token) {
      header["Authorization"] = `Bearer ${token}`;
    }

    wx.uploadFile({
      url: fullUrl,
      filePath: filePath,
      name: options.name || "file",
      header: header,
      success: (res) => {
        // 隐藏加载中
        if (options.showLoading !== false) {
          wx.hideLoading();
        }

        try {
          const data = JSON.parse(res.data);
          resolve(data);
        } catch (error) {
          reject(new Error("解析响应失败"));
        }
      },
      fail: (error) => {
        // 隐藏加载中
        if (options.showLoading !== false) {
          wx.hideLoading();
        }

        reject(error);
      },
    });
  });
}

// 导出方法
module.exports = {
  request,
  get,
  post,
  put,
  delete: del,
  upload,
};
